import tkinter as tk
from tkinter import filedialog, ttk, messagebox
import sqlite3
import pandas as pd
import os
import threading


class DatabaseComparatorApp:
    def __init__(self, root):
        self.root = root
        self.root.title("数据库对比工具")
        self.root.geometry("1200x800")
        self.root.minsize(1000, 700)

        # 设置字体，确保中文显示正常
        self.default_font = ('Microsoft YaHei UI', 10)
        self.header_font = ('Microsoft YaHei UI', 12, 'bold')
        self.title_font = ('Microsoft YaHei UI', 14, 'bold')

        # 存储数据库信息
        self.source_db = None
        self.target_db = None
        self.comparison_result = None

        # 创建带滚动条的主容器
        self.create_scrollable_container()

        # 创建界面内容
        self.create_widgets()

    def create_scrollable_container(self):
        """创建带纵向滚动条的主容器"""
        # 主容器框架
        container = ttk.Frame(self.root)
        container.pack(fill=tk.BOTH, expand=True)

        # 纵向滚动条
        self.scrollbar = ttk.Scrollbar(container, orient=tk.VERTICAL)
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        # 创建Canvas作为滚动区域
        self.canvas = tk.Canvas(container, yscrollcommand=self.scrollbar.set)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 关联滚动条和Canvas
        self.scrollbar.config(command=self.canvas.yview)

        # 创建主内容框架，放置在Canvas上
        self.main_frame = ttk.Frame(self.canvas)
        self.canvas_window = self.canvas.create_window((0, 0), window=self.main_frame, anchor=tk.NW)

        # 绑定事件处理滚动区域调整
        self.main_frame.bind("<Configure>", self.on_main_frame_configure)
        self.canvas.bind("<Configure>", self.on_canvas_configure)

        # 支持鼠标滚轮滚动
        self.canvas.bind_all("<MouseWheel>", self.on_mouse_wheel)

    def on_main_frame_configure(self, event):
        """当主框架大小改变时更新滚动区域"""
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def on_canvas_configure(self, event):
        """当Canvas大小改变时调整主框架宽度"""
        canvas_width = event.width
        self.canvas.itemconfig(self.canvas_window, width=canvas_width)

    def on_mouse_wheel(self, event):
        """处理鼠标滚轮事件实现滚动"""
        self.canvas.yview_scroll(-int(event.delta / 120), "units")

    def create_widgets(self):
        # 标题
        title_label = ttk.Label(self.main_frame, text="数据库对比工具", font=self.title_font)
        title_label.pack(pady=(15, 15))

        # 文件选择区域
        file_frame = ttk.LabelFrame(self.main_frame, text="选择数据库文件", padding=15)
        file_frame.pack(fill=tk.X, pady=(0, 10), padx=15)

        # 源数据库选择
        source_frame = ttk.Frame(file_frame)
        source_frame.pack(fill=tk.X, pady=5)
        ttk.Label(source_frame, text="源数据库:", font=self.default_font, width=10, anchor=tk.W).pack(side=tk.LEFT)
        self.source_path_var = tk.StringVar()
        ttk.Entry(source_frame, textvariable=self.source_path_var, font=self.default_font).pack(side=tk.LEFT, fill=tk.X,
                                                                                                expand=True, padx=5)
        ttk.Button(source_frame, text="浏览...", command=self.browse_source_db, width=8).pack(side=tk.LEFT)

        # 目标数据库选择
        target_frame = ttk.Frame(file_frame)
        target_frame.pack(fill=tk.X, pady=5)
        ttk.Label(target_frame, text="目标数据库:", font=self.default_font, width=10, anchor=tk.W).pack(side=tk.LEFT)
        self.target_path_var = tk.StringVar()
        ttk.Entry(target_frame, textvariable=self.target_path_var, font=self.default_font).pack(side=tk.LEFT, fill=tk.X,
                                                                                                expand=True, padx=5)
        ttk.Button(target_frame, text="浏览...", command=self.browse_target_db, width=8).pack(side=tk.LEFT)

        # 对比按钮
        button_frame = ttk.Frame(file_frame)
        button_frame.pack(fill=tk.X, pady=(15, 0))
        self.compare_button = ttk.Button(button_frame, text="开始对比", command=self.compare_databases,
                                         style='Accent.TButton')
        self.compare_button.pack(side=tk.RIGHT)

        # 结果显示区域 - 使用Notebook创建选项卡
        self.notebook = ttk.Notebook(self.main_frame)
        self.notebook.pack(fill=tk.BOTH, expand=True, pady=10, padx=15)

        # 表结构对比选项卡
        structure_frame = ttk.Frame(self.notebook)
        self.notebook.add(structure_frame, text="表结构对比")

        # 结构对比左右分栏
        structure_split = ttk.PanedWindow(structure_frame, orient=tk.HORIZONTAL)
        structure_split.pack(fill=tk.BOTH, expand=True)

        # 源数据库结构
        source_structure_frame = ttk.LabelFrame(structure_split, text="源数据库结构", padding=5)
        structure_split.add(source_structure_frame, weight=1)

        self.source_tree = ttk.Treeview(source_structure_frame, columns=('column', 'type', 'pk'), show='headings')
        self.source_tree.heading('column', text='列名')
        self.source_tree.heading('type', text='类型')
        self.source_tree.heading('pk', text='主键')
        self.source_tree.column('column', width=150)
        self.source_tree.column('type', width=100)
        self.source_tree.column('pk', width=50, anchor=tk.CENTER)

        source_scroll_y = ttk.Scrollbar(source_structure_frame, orient=tk.VERTICAL, command=self.source_tree.yview)
        source_scroll_x = ttk.Scrollbar(source_structure_frame, orient=tk.HORIZONTAL, command=self.source_tree.xview)
        self.source_tree.configure(yscrollcommand=source_scroll_y.set, xscrollcommand=source_scroll_x.set)

        source_scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
        source_scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.source_tree.pack(fill=tk.BOTH, expand=True)

        # 目标数据库结构
        target_structure_frame = ttk.LabelFrame(structure_split, text="目标数据库结构", padding=5)
        structure_split.add(target_structure_frame, weight=1)

        self.target_tree = ttk.Treeview(target_structure_frame, columns=('column', 'type', 'pk'), show='headings')
        self.target_tree.heading('column', text='列名')
        self.target_tree.heading('type', text='类型')
        self.target_tree.heading('pk', text='主键')
        self.target_tree.column('column', width=150)
        self.target_tree.column('type', width=100)
        self.target_tree.column('pk', width=50, anchor=tk.CENTER)

        target_scroll_y = ttk.Scrollbar(target_structure_frame, orient=tk.VERTICAL, command=self.target_tree.yview)
        target_scroll_x = ttk.Scrollbar(target_structure_frame, orient=tk.HORIZONTAL, command=self.target_tree.xview)
        self.target_tree.configure(yscrollcommand=target_scroll_y.set, xscrollcommand=target_scroll_x.set)

        target_scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
        target_scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.target_tree.pack(fill=tk.BOTH, expand=True)

        # 表选择区域
        table_select_frame = ttk.LabelFrame(self.main_frame, text="选择表查看数据", padding=10)
        table_select_frame.pack(fill=tk.X, pady=5, padx=15)

        table_select_inner_frame = ttk.Frame(table_select_frame)
        table_select_inner_frame.pack(fill=tk.X)

        ttk.Label(table_select_inner_frame, text="选择表:", font=self.default_font).pack(side=tk.LEFT, padx=5)
        self.table_combo = ttk.Combobox(table_select_inner_frame, state="disabled", width=30, font=self.default_font)
        self.table_combo.pack(side=tk.LEFT, padx=5)
        self.table_combo.bind("<<ComboboxSelected>>", self.on_table_selected)

        # 数据对比选项卡
        data_frame = ttk.Frame(self.notebook)
        self.notebook.add(data_frame, text="表数据对比")

        # 数据对比左右分栏
        data_split = ttk.PanedWindow(data_frame, orient=tk.HORIZONTAL)
        data_split.pack(fill=tk.BOTH, expand=True)

        # 源数据库数据
        source_data_frame = ttk.LabelFrame(data_split, text="源数据库数据", padding=5)
        data_split.add(source_data_frame, weight=1)

        self.source_data_tree = ttk.Treeview(source_data_frame, show='headings')
        source_data_scroll_y = ttk.Scrollbar(source_data_frame, orient=tk.VERTICAL, command=self.source_data_tree.yview)
        source_data_scroll_x = ttk.Scrollbar(source_data_frame, orient=tk.HORIZONTAL,
                                             command=self.source_data_tree.xview)
        self.source_data_tree.configure(yscrollcommand=source_data_scroll_y.set,
                                        xscrollcommand=source_data_scroll_x.set)

        source_data_scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
        source_data_scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.source_data_tree.pack(fill=tk.BOTH, expand=True)

        # 目标数据库数据
        target_data_frame = ttk.LabelFrame(data_split, text="目标数据库数据", padding=5)
        data_split.add(target_data_frame, weight=1)

        self.target_data_tree = ttk.Treeview(target_data_frame, show='headings')
        target_data_scroll_y = ttk.Scrollbar(target_data_frame, orient=tk.VERTICAL, command=self.target_data_tree.yview)
        target_data_scroll_x = ttk.Scrollbar(target_data_frame, orient=tk.HORIZONTAL,
                                             command=self.target_data_tree.xview)
        self.target_data_tree.configure(yscrollcommand=target_data_scroll_y.set,
                                        xscrollcommand=target_data_scroll_x.set)

        target_data_scroll_y.pack(side=tk.RIGHT, fill=tk.Y)
        target_data_scroll_x.pack(side=tk.BOTTOM, fill=tk.X)
        self.target_data_tree.pack(fill=tk.BOTH, expand=True)

        # 统计信息区域
        stats_frame = ttk.LabelFrame(self.main_frame, text="对比统计", padding=10)
        stats_frame.pack(fill=tk.X, pady=(10, 15), padx=15)

        stats_inner_frame = ttk.Frame(stats_frame)
        stats_inner_frame.pack(fill=tk.X)

        # 第一行统计信息
        stats_row1 = ttk.Frame(stats_inner_frame)
        stats_row1.pack(fill=tk.X, pady=2)

        ttk.Label(stats_row1, text="总表数:", font=self.default_font, width=10, anchor=tk.W).pack(side=tk.LEFT)
        self.total_tables_var = tk.StringVar(value="0")
        ttk.Label(stats_row1, textvariable=self.total_tables_var, font=self.header_font, foreground='#2196F3').pack(
            side=tk.LEFT)

        ttk.Label(stats_row1, text="结构差异:", font=self.default_font, width=12, anchor=tk.W).pack(side=tk.LEFT,
                                                                                                    padx=(20, 0))
        self.structure_diff_var = tk.StringVar(value="0")
        ttk.Label(stats_row1, textvariable=self.structure_diff_var, font=self.header_font, foreground='#F44336').pack(
            side=tk.LEFT)

        ttk.Label(stats_row1, text="数据差异:", font=self.default_font, width=12, anchor=tk.W).pack(side=tk.LEFT,
                                                                                                    padx=(20, 0))
        self.data_diff_var = tk.StringVar(value="0")
        ttk.Label(stats_row1, textvariable=self.data_diff_var, font=self.header_font, foreground='#FF9800').pack(
            side=tk.LEFT)

        # 修复：使用tkinter原生Label而非ttk.Label，并使用pady选项
        tk.Label(self.main_frame, text="").pack(pady=20)

        # 状态栏（固定在窗口底部）
        self.status_var = tk.StringVar(value="就绪")
        self.status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W, padding=5)
        self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)

        # 配置样式
        style = ttk.Style()
        style.configure('Accent.TButton', font=self.default_font, fontweight='bold')
        style.configure('Treeview', font=self.default_font, rowheight=25)
        style.configure('Treeview.Heading', font=self.default_font, fontweight='bold')

        # 配置标签框架样式
        style.configure('TLabelframe.Label', font=self.header_font)

        # 配置差异标记样式
        self.source_tree.tag_configure('missing_in_target', background='#FFEBEE', foreground='#F44336')
        self.source_tree.tag_configure('modified', background='#FFF3E0', foreground='#FF9800')
        self.target_tree.tag_configure('missing_in_source', background='#FFEBEE', foreground='#F44336')
        self.target_tree.tag_configure('modified', background='#FFF3E0', foreground='#FF9800')

        # 配置数据树样式
        self.source_data_tree.tag_configure('oddrow', background='#F5F5F5')
        self.target_data_tree.tag_configure('oddrow', background='#F5F5F5')

    def browse_source_db(self):
        file_path = filedialog.askopenfilename(
            title="选择源数据库文件",
            filetypes=[("SQLite数据库", "*.db;*.sqlite;*.sqlite3"),
                       ("Excel文件", "*.xls;*.xlsx"),
                       ("CSV文件", "*.csv"),
                       ("所有文件", "*.*")]
        )
        if file_path:
            self.source_path_var.set(file_path)

    def browse_target_db(self):
        file_path = filedialog.askopenfilename(
            title="选择目标数据库文件",
            filetypes=[("SQLite数据库", "*.db;*.sqlite;*.sqlite3"),
                       ("Excel文件", "*.xls;*.xlsx"),
                       ("CSV文件", "*.csv"),
                       ("所有文件", "*.*")]
        )
        if file_path:
            self.target_path_var.set(file_path)

    def compare_databases(self):
        source_path = self.source_path_var.get()
        target_path = self.target_path_var.get()

        if not source_path or not target_path:
            messagebox.showerror("错误", "请选择源数据库和目标数据库文件")
            return

        # 清空之前的结果
        self.clear_results()

        # 禁用对比按钮
        self.compare_button.config(state=tk.DISABLED)
        self.status_var.set("正在对比数据库...")

        # 在新线程中执行对比，避免界面卡顿
        threading.Thread(target=self._compare_databases_thread, daemon=True).start()

    def _compare_databases_thread(self):
        try:
            source_path = self.source_path_var.get()
            target_path = self.target_path_var.get()

            # 解析数据库
            self.status_var.set("正在解析源数据库...")
            self.source_db = self.parse_database(source_path)

            self.status_var.set("正在解析目标数据库...")
            self.target_db = self.parse_database(target_path)

            # 对比数据库
            self.status_var.set("正在对比数据库结构...")
            self.comparison_result = self.compare_db_structures(self.source_db, self.target_db)

            # 更新UI显示结果
            self.root.after(0, self.update_comparison_results)

            # 显示对比完成的弹窗提示
            self.root.after(0, self.show_comparison_summary)

            self.status_var.set("对比完成!")
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("错误", f"对比过程中出错: {str(e)}"))
            self.status_var.set("对比失败!!!")
        finally:
            # 恢复按钮状态
            self.root.after(0, lambda: self.compare_button.config(state=tk.NORMAL))

    def show_comparison_summary(self):
        """显示对比结果摘要的弹窗"""
        if not self.comparison_result:
            return

        stats = self.comparison_result['stats']
        total_tables = stats['total_tables']
        structure_diff = stats['structure_differences']
        data_diff = stats['data_differences']

        # 构建弹窗消息
        message = f"数据库对比完成！\n\n"
        message += f"总表数: {total_tables}\n"
        message += f"结构差异表数: {structure_diff}\n"
        message += f"数据差异表数: {data_diff}\n\n"

        if structure_diff == 0 and data_diff == 0:
            message += "两个数据库完全一致!"
        else:
            message += "发现差异，请查看详细结果。"

        messagebox.showinfo("对比结果摘要", message)

    def parse_database(self, db_path):
        """解析数据库文件，获取表结构和数据"""
        file_ext = os.path.splitext(db_path)[1].lower()
        db_info = {"tables": {}}

        if file_ext in ['.db', '.sqlite', '.sqlite3']:
            # SQLite数据库
            try:
                conn = sqlite3.connect(db_path)
                cursor = conn.cursor()

                # 获取所有表名
                cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
                table_names = [row[0] for row in cursor.fetchall()]

                for table_name in table_names:
                    # 获取表结构
                    cursor.execute(f"PRAGMA table_info({table_name})")
                    columns = cursor.fetchall()

                    table_columns = []
                    for column in columns:
                        table_columns.append({
                            'name': column[1],
                            'type': column[2],
                            'notnull': column[3],
                            'primary_key': column[5]
                        })

                    # 获取表记录数
                    cursor.execute(f"SELECT COUNT(*) FROM {table_name}")
                    record_count = cursor.fetchone()[0]

                    # 获取表数据（限制为前1000条记录，避免大数据量导致内存问题）
                    if record_count > 0:
                        cursor.execute(f"SELECT * FROM {table_name} LIMIT 1000")
                        rows = cursor.fetchall()

                        # 获取列名
                        column_names = [col['name'] for col in table_columns]

                        # 转换为字典列表
                        data = []
                        for row in rows:
                            row_dict = {}
                            for i, value in enumerate(row):
                                row_dict[column_names[i]] = value
                            data.append(row_dict)
                    else:
                        data = []

                    db_info["tables"][table_name] = {
                        'columns': table_columns,
                        'record_count': record_count,
                        'data': data
                    }

                conn.close()
            except Exception as e:
                messagebox.showerror("错误", f"无法解析SQLite数据库: {str(e)}")
                return {"tables": {}}

        elif file_ext in ['.xls', '.xlsx']:
            # Excel文件
            try:
                excel_file = pd.ExcelFile(db_path)
                sheet_names = excel_file.sheet_names

                for sheet_name in sheet_names:
                    df = excel_file.parse(sheet_name)
                    columns = [{'name': col, 'type': str(df[col].dtype), 'notnull': False, 'primary_key': False} for col
                               in df.columns]

                    db_info["tables"][sheet_name] = {
                        'columns': columns,
                        'record_count': len(df),
                        'data': df.to_dict('records')  # 存储数据行
                    }
            except Exception as e:
                messagebox.showerror("错误", f"无法解析Excel文件: {str(e)}")
                return {"tables": {}}

        elif file_ext == '.csv':
            # CSV文件
            try:
                df = pd.read_csv(db_path)
                columns = [{'name': col, 'type': str(df[col].dtype), 'notnull': False, 'primary_key': False} for col in
                           df.columns]

                db_info["tables"]["data"] = {
                    'columns': columns,
                    'record_count': len(df),
                    'data': df.to_dict('records')  # 存储数据行
                }
            except Exception as e:
                messagebox.showerror("错误", f"无法解析CSV文件: {str(e)}")
                return {"tables": {}}

        else:
            messagebox.showerror("错误", f"不支持的文件类型: {file_ext}")
            return {"tables": {}}

        return db_info

    def compare_db_structures(self, source_db, target_db):
        """比较两个数据库的结构差异"""
        comparison = {
            'tables': [],
            'stats': {
                'total_tables': 0,
                'structure_differences': 0,
                'data_differences': 0
            }
        }

        # 获取所有表名
        all_table_names = set(source_db["tables"].keys()).union(set(target_db["tables"].keys()))
        comparison['stats']['total_tables'] = len(all_table_names)

        for table_name in all_table_names:
            source_table = source_db["tables"].get(table_name)
            target_table = target_db["tables"].get(table_name)

            table_comparison = {
                'name': table_name,
                'source': source_table,
                'target': target_table,
                'differences': {
                    'structure': False,
                    'columns': []
                }
            }

            # 检查表是否存在于两个数据库中
            if source_table and target_table:
                # 检查列差异
                source_columns = {col['name']: col for col in source_table['columns']}
                target_columns = {col['name']: col for col in target_table['columns']}

                # 检查所有源列是否存在于目标中
                for col_name, col_info in source_columns.items():
                    target_col = target_columns.get(col_name)
                    if not target_col:
                        table_comparison['differences']['structure'] = True
                        table_comparison['differences']['columns'].append({
                            'name': col_name,
                            'type': col_info['type'],
                            'status': 'missing_in_target'
                        })
                    else:
                        # 检查列类型和约束差异
                        if col_info['type'] != target_col['type'] or col_info['primary_key'] != target_col[
                            'primary_key']:
                            table_comparison['differences']['structure'] = True
                            table_comparison['differences']['columns'].append({
                                'name': col_name,
                                'source_type': col_info['type'],
                                'target_type': target_col['type'],
                                'status': 'modified'
                            })

                # 检查所有目标列是否存在于源中
                for col_name, col_info in target_columns.items():
                    if col_name not in source_columns:
                        table_comparison['differences']['structure'] = True
                        table_comparison['differences']['columns'].append({
                            'name': col_name,
                            'type': col_info['type'],
                            'status': 'missing_in_source'
                        })

                # 检查记录数差异作为数据差异的简单指标
                if source_table['record_count'] != target_table['record_count']:
                    table_comparison['differences']['data'] = True

            elif source_table and not target_table:
                table_comparison['differences']['structure'] = True
                table_comparison['differences']['data'] = True
                table_comparison['differences']['columns'] = [
                    {'name': col['name'], 'type': col['type'], 'status': 'missing_in_target'}
                    for col in source_table['columns']
                ]

            elif target_table and not source_table:
                table_comparison['differences']['structure'] = True
                table_comparison['differences']['data'] = True
                table_comparison['differences']['columns'] = [
                    {'name': col['name'], 'type': col['type'], 'status': 'missing_in_source'}
                    for col in target_table['columns']
                ]

            # 更新统计信息
            if table_comparison['differences']['structure']:
                comparison['stats']['structure_differences'] += 1
            if table_comparison['differences'].get('data', False):
                comparison['stats']['data_differences'] += 1

            comparison['tables'].append(table_comparison)

        return comparison

    def update_comparison_results(self):
        """更新界面显示对比结果"""
        if not self.comparison_result:
            return

        # 更新统计信息
        self.total_tables_var.set(str(self.comparison_result['stats']['total_tables']))
        self.structure_diff_var.set(str(self.comparison_result['stats']['structure_differences']))
        self.data_diff_var.set(str(self.comparison_result['stats']['data_differences']))

        # 更新表下拉列表
        table_names = [table['name'] for table in self.comparison_result['tables']]
        self.table_combo['values'] = table_names
        self.table_combo['state'] = 'readonly'

        # 默认选择第一个表
        if table_names:
            self.table_combo.current(0)
            self.on_table_selected(None)

    def on_table_selected(self, event):
        """处理表选择事件"""
        table_name = self.table_combo.get()
        if not table_name or not self.comparison_result:
            return

        # 查找选中的表
        selected_table = next(
            (table for table in self.comparison_result['tables'] if table['name'] == table_name),
            None
        )

        if not selected_table:
            return

        # 清空树视图
        for item in self.source_tree.get_children():
            self.source_tree.delete(item)
        for item in self.target_tree.get_children():
            self.target_tree.delete(item)

        # 显示源表结构
        if selected_table['source']:
            for i, col in enumerate(selected_table['source']['columns']):
                # 检查列是否存在差异
                diff_col = next(
                    (c for c in selected_table['differences']['columns'] if c['name'] == col['name']),
                    None
                )

                tags = ()
                if diff_col:
                    if diff_col['status'] == 'missing_in_target':
                        tags = ('missing_in_target',)
                    elif diff_col['status'] == 'modified':
                        tags = ('modified',)

                self.source_tree.insert(
                    '', 'end',
                    values=(col['name'], col['type'], '✓' if col['primary_key'] else ''),
                    tags=tags
                )

        # 显示目标表结构
        if selected_table['target']:
            for i, col in enumerate(selected_table['target']['columns']):
                # 检查列是否存在差异
                diff_col = next(
                    (c for c in selected_table['differences']['columns'] if c['name'] == col['name']),
                    None
                )

                tags = ()
                if diff_col:
                    if diff_col['status'] == 'missing_in_source':
                        tags = ('missing_in_source',)
                    elif diff_col['status'] == 'modified':
                        tags = ('modified',)

                self.target_tree.insert(
                    '', 'end',
                    values=(col['name'], col['type'], '✓' if col['primary_key'] else ''),
                    tags=tags
                )

        # 显示表数据
        self.show_table_data(selected_table)

    def show_table_data(self, table_comparison):
        """显示表数据对比"""
        table_name = table_comparison['name']
        source_table = table_comparison['source']
        target_table = table_comparison['target']

        # 清空数据树视图
        for item in self.source_data_tree.get_children():
            self.source_data_tree.delete(item)
        for item in self.target_data_tree.get_children():
            self.target_data_tree.delete(item)

        # 设置列
        if source_table:
            self.setup_data_tree_columns(self.source_data_tree, source_table['columns'])
        if target_table:
            self.setup_data_tree_columns(self.target_data_tree, target_table['columns'])

        # 加载数据
        if source_table and source_table.get('data'):
            self.load_data(self.source_data_tree, source_table['data'])

        if target_table and target_table.get('data'):
            self.load_data(self.target_data_tree, target_table['data'])

        # 显示表存在状态信息
        self.show_table_status_info(table_comparison)

    def show_table_status_info(self, table_comparison):
        """显示表的结构和数据差异信息，以及表只存在于一个数据库的情况"""
        table_name = table_comparison['name']
        source_exists = table_comparison['source'] is not None
        target_exists = table_comparison['target'] is not None
        structure_diff = table_comparison['differences']['structure']
        data_diff = table_comparison['differences'].get('data', False)

        # 在状态栏显示表的状态信息
        status_info = f"表 '{table_name}': "

        if not source_exists and target_exists:
            status_info += "只存在于目标数据库中"
        elif source_exists and not target_exists:
            status_info += "只存在于源数据库中 "
        elif not source_exists and not target_exists:
            status_info += "在两个数据库中都不存在"
        else:
            # 两个数据库都存在该表
            if structure_diff:
                status_info += "结构不一致!!!!!! "
            else:
                status_info += "结构一致!  "

            if data_diff:
                status_info += "数据不一致!!!!!!  "
            else:
                status_info += "数据一致!  "

        self.status_var.set(status_info)
        
        # 根据一致性状态设置颜色
        if (source_exists and target_exists and not structure_diff and not data_diff):
            # 一致情况：绿色
            self.status_bar.configure(foreground='green')
        else:
            # 不一致情况：红色
            self.status_bar.configure(foreground='red')

    def setup_data_tree_columns(self, tree, columns):
        """设置数据树视图的列"""
        # 清空现有列
        tree['columns'] = []

        # 设置新列
        for col in columns:
            tree['columns'] = [col['name'] for col in columns]

        # 设置列标题和宽度
        for col in columns:
            tree.heading(col['name'], text=col['name'])
            # 根据列类型设置宽度
            if 'id' in col['name'].lower() or 'key' in col['name'].lower():
                tree.column(col['name'], width=80, anchor=tk.CENTER)
            elif 'date' in col['name'].lower() or 'time' in col['name'].lower():
                tree.column(col['name'], width=120, anchor=tk.CENTER)
            elif 'amount' in col['name'].lower() or 'price' in col['name'].lower():
                tree.column(col['name'], width=100, anchor=tk.RIGHT)
            else:
                tree.column(col['name'], width=150, anchor=tk.CENTER)

    def load_data(self, tree, data):
        """加载实际数据到树视图"""
        if not data or len(data) == 0:
            return

        # 获取列名
        columns = list(data[0].keys())

        # 添加数据行
        for i, row_data in enumerate(data):
            values = [row_data.get(col, '') for col in columns]
            # 交替行颜色
            tags = ('oddrow',) if i % 2 == 1 else ()
            tree.insert('', 'end', values=values, tags=tags)

    def clear_results(self):
        """清空结果显示"""
        # 清空树视图
        for item in self.source_tree.get_children():
            self.source_tree.delete(item)
        for item in self.target_tree.get_children():
            self.target_tree.delete(item)
        for item in self.source_data_tree.get_children():
            self.source_data_tree.delete(item)
        for item in self.target_data_tree.get_children():
            self.target_data_tree.delete(item)

        # 清空下拉列表
        self.table_combo['values'] = []
        self.table_combo['state'] = 'disabled'

        # 重置统计信息
        self.total_tables_var.set("0")
        self.structure_diff_var.set("0")
        self.data_diff_var.set("0")

        # 重置状态栏
        self.status_var.set("就绪")
        self.status_bar.configure(foreground='black')  # 重置状态栏颜色


if __name__ == "__main__":
    root = tk.Tk()
    app = DatabaseComparatorApp(root)
    root.mainloop()